using UnityEngine;
using UnityEngine.Rendering;
//[ExecuteInEditMode]
public class MeshBall : MonoBehaviour
{
    static int baseColorId = Shader.PropertyToID("_BaseColor"),
                metallicId = Shader.PropertyToID("_Metallic"),
                somoothnessId = Shader.PropertyToID("_Smoothness"),
                alphaoffId = Shader.PropertyToID("_Cutoff");
    float[] metallic = new float[1023], smoothness = new float[1023], alphaoff = new float[1023];
    [SerializeField]
    Mesh mesh = default;

    [SerializeField]
    Material material = default;

    Matrix4x4[] matrices = new Matrix4x4[1023];
    Vector4[] baseColors = new Vector4[1023];
    MaterialPropertyBlock block;
    [SerializeField]
    LightProbeProxyVolume lightProbeVolume = null;

    private void Awake()
    {
        for (int i = 0; i < matrices.Length; i++)
        {
            matrices[i] = Matrix4x4.TRS(Random.insideUnitSphere * 10f, Quaternion.Euler(Random.value * 360f, Random.value * 360f, Random.value * 360f), Vector3.one * Random.Range(0.5f, 1.5f));
            baseColors[i] = new Vector4(Random.value, Random.value, Random.value, Random.Range(0.5f, 1f));
            metallic[i] = Random.value < 0.25f ? 1f : 0f;
            smoothness[i] = Random.Range(0.05f, 0.95f);
            alphaoff[i] = Random.Range(0, 1);
        }
    }
    private void Update()
    {
        if (block == null)
        {
            block = new MaterialPropertyBlock();
            block.SetVectorArray(baseColorId, baseColors);
            block.SetFloatArray(metallicId, metallic);
            block.SetFloatArray(somoothnessId, smoothness);
            block.SetFloatArray(alphaoffId, alphaoff);

            var positions = new Vector3[1023];
            var occlusionProbes = new Vector4[1023];
            for (int i = 0; i < matrices.Length; i++)
            {
                positions[i] = matrices[i].GetColumn(3);
            }
            if (!lightProbeVolume)
            {
                var lightProbes = new SphericalHarmonicsL2[1023];
                LightProbes.CalculateInterpolatedLightAndOcclusionProbes(positions, lightProbes, null);
                block.CopySHCoefficientArraysFrom(lightProbes);
                block.CopyProbeOcclusionArrayFrom(occlusionProbes);
            }
        }
        Graphics.DrawMeshInstanced(
            mesh, 0, material, matrices, 1023, block,
            ShadowCastingMode.On, true, 0, null, lightProbeVolume ? LightProbeUsage.UseProxyVolume : LightProbeUsage.CustomProvided,
            lightProbeVolume
        );
    }

}
